home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / asm_msc1.arc / ALARM.ASM next >
Assembly Source File  |  1988-11-20  |  8KB  |  372 lines

  1. cseg    segment para public 'code'
  2. org    100h
  3. alarm    proc far
  4.  
  5. ; Memory-resident program to intercept the timer interrupt and display the
  6. ; system time in the upper right-hand corner of the display.
  7. ; This program is run as 'ALARM hh:mm x', where hh:mm is the alarm time and
  8. ; x is '-' to turn the display off. Any other value of x or no value will
  9. ; turn the clock on
  10.  
  11. intaddr equ 1ch*4        ; interrupt address
  12. segaddr equ 62h*4        ; segment address of first copy
  13. mfactor equ 17478        ; minute conversion factor * 16
  14. whozat    equ 1234h        ; signature
  15.  
  16.     assume cs:cseg,ds:cseg,ss:nothing,es:nothing
  17.     jmp p150        ; start-up code
  18.  
  19. jumpval dd 0            ; address of prior interrupt
  20. signature dw whozat        ; program signature
  21. state    db 0            ; '-' = off, all else = on
  22. wait    dw 18            ; wait time - 1 second or 18 ticks
  23. hour    dw 0            ; hour of the day
  24. atime    dw 0ffffh        ; minutes past midnite for alarm
  25. acount    dw 0            ; alarm beep counter - number of seconds (5)
  26. atone    db 5            ; alarm tone - may be from 1 to 255 - the
  27.                 ; higher the number, the lower the frequency
  28. aleng    dw 8080h        ; alarm length (loop count) may be from 1-FFFF
  29. coords    dw 0            ; original cursor location
  30.  
  31. dhours    dw 0            ; display hours
  32.     db ':'
  33. dmins    dw 0            ; display minutes
  34.     db ':'
  35. dsecs    dw 0            ; display seconds
  36.     db ' '
  37. ampm    db 0            ; 'A' or 'P' for am or pm
  38.     db 'M'
  39.  
  40. tstack    db 16 dup('stack   ')   ; temporary stack
  41. estack    db 0            ; end of stack
  42. holdsp    dw 0            ; original sp
  43. holdss    dw 0            ; original ss
  44.  
  45. p000:                ; interrupt code
  46.     push ax         ; save registers
  47.     push ds
  48.     pushf
  49.  
  50.     push cs
  51.     pop ds            ; make ds=cs
  52.     mov ax,wait        ; check wait time
  53.     dec ax            ; zero?
  54.     jz p010         ; yes - 1 second has elapsed
  55.     mov wait,ax        ; not this time
  56.     jmp p080        ; return
  57.  
  58. p010:    cli            ; disable interrupts
  59.     mov ax,ss        ; save stack
  60.     mov holdss,ax
  61.     mov holdsp,sp
  62.     mov ax,ds
  63.     mov ss,ax        ; point to internal stack
  64.     mov sp,offset estack
  65.     sti            ; allow interrupts
  66.  
  67.     push bx         ; save other registers
  68.     push cx
  69.     push dx
  70.     push es
  71.     push si
  72.     push di
  73.     push bp
  74.  
  75.     mov ax,18        ; reset wait time
  76.     mov wait,ax
  77.  
  78.     mov al,state        ; are we disabled?
  79.     cmp al,'-'
  80.     jnz p015        ; no
  81.     jmp p070
  82.  
  83. p015:    mov ah,3        ; get cursor position
  84.     mov bh,0
  85.     int 10h
  86.     mov coords,dx        ; save it
  87.  
  88.     mov ah,0        ; read time
  89.     int 1ah         ; get time of day
  90.     mov ax,dx        ; low part
  91.     mov dx,cx        ; high part
  92.     mov cl,4
  93.     shl dx,cl        ; multiply by 16
  94.     mov bx,ax
  95.     mov cl,12
  96.     shr bx,cl        ; isolate top 4 bits of ax
  97.     add dx,bx        ; now in upper
  98.     mov cl,4
  99.     shl ax,cl        ; multiply by 16
  100.     mov bx,mfactor        ; compute minutes
  101.     div bx            ; minutes in ax, remainder in dx
  102.     cmp ax,atime        ; time to sound the alarm?
  103.     jnz p020        ; no
  104.     call p100        ; yes - beep the speaker twice
  105.     push ax
  106.     mov ax,acount        ; get beep count
  107.     dec ax            ; down by 1
  108.     mov acount,ax        ; save beep count
  109.     cmp ax,0        ; is it zero?
  110.     jnz p018        ; no - keep alarm on
  111.     mov ax,0ffffh        ; turn off alarm
  112.     mov atime,ax
  113. p018:    pop ax
  114.  
  115. p020:    mov dsecs,dx        ; save remainder
  116.     mov bx,60        ; compute hours
  117.     xor dx,dx        ; zero it
  118.     div bx            ; hours in ax, minutes in dx
  119.     mov dmins,dx        ; save minutes
  120.  
  121.     cmp ax,0        ; midnight?
  122.     jnz p030        ; no
  123.     mov ax,12        ; yes
  124.     jmp p040a        ; set am
  125.  
  126. p030:    cmp ax,12        ; before noon?
  127.     jb p040a        ; yes - set am
  128.     jz p040p        ; noon - set pm
  129.     sub ax,12        ; convert the rest
  130. p040p:    mov bl,'P'
  131.     jmp p040x
  132.  
  133. p040a:    mov bl,'A'
  134.  
  135. p040x:    mov ampm,bl
  136.     aam            ; fix up hour
  137.     cmp ax,hour        ; top of the hour?
  138.     jz p060         ; no
  139.  
  140.     mov hour,ax
  141.     call p120        ; beep the speaker once
  142.  
  143. p060:    add ax,3030h        ; convert hours to ascii
  144.     xchg ah,al
  145.     mov dhours,ax
  146.  
  147.     mov ax,dmins        ; get minutes
  148.     aam
  149.     add ax,3030h        ; convert to ascii
  150.     xchg ah,al
  151.     mov dmins,ax
  152.  
  153.     mov ax,dsecs        ; get seconds (remainder)
  154.     xor dx,dx
  155.     mov bx,60
  156.     mul bx
  157.     mov bx,mfactor
  158.     div bx            ; seconds in ax
  159.     aam
  160.     add ax,3030h
  161.     xchg ah,al
  162.     mov dsecs,ax
  163.  
  164.     mov ah,2        ; move to row 1, column 70
  165.     mov bh,0
  166.     mov dx,69
  167.     int 10h
  168.  
  169.     mov si,offset dhours    ; display time
  170.     mov bl,70h        ; color attribute
  171.     mov dx,11        ; loop count
  172.  
  173. p065:    mov al,[si]
  174.     mov ah,9
  175.     mov cx,1
  176.     push si
  177.     int 10h         ; write char/attr.
  178.  
  179.     push dx
  180.     mov ah,3        ; get cursor position
  181.     int 10h
  182.     inc dl            ; advance 1 column
  183.     mov ah,2
  184.     int 10h
  185.     pop dx
  186.  
  187.     pop si
  188.     inc si
  189.     dec dx
  190.     cmp dx,0
  191.     jnz p065
  192.  
  193.     mov dx,coords        ; restore cursor position
  194.     mov bh,0
  195.     mov ah,2
  196.     int 10h
  197.  
  198. p070:
  199.     pop bp            ; restore registers
  200.     pop di
  201.     pop si
  202.     pop es
  203.     pop dx
  204.     pop cx
  205.     pop bx
  206.     cli            ; no interrupts
  207.     mov ax,holdss
  208.     mov ss,ax
  209.     mov sp,holdsp
  210.     sti            ; allow interrupts
  211.  
  212. p080:    popf
  213.     pop ds
  214.     pop ax
  215.     jmp cs:[jumpval]
  216.  
  217. p100    proc near        ; beep the speaker twice
  218.     call p120
  219.     push cx
  220.     mov cx,20000
  221. p105:    loop p105        ; wait around
  222.     pop cx
  223.     call p120
  224.     ret
  225. p100    endp
  226.  
  227. p120    proc near        ; beep the speaker once
  228.     push ax
  229.     push cx
  230.     mov al,182
  231.     out 43h,al        ; setup for sound
  232.     mov al,0
  233.     out 42h,al        ; low part
  234.     mov al,atone        ; get alarm tone
  235.     out 42h,al        ; high part
  236.     in al,61h
  237.     push ax         ; save port value
  238.     or al,3
  239.     out 61h,al        ; turn speaker on
  240.     mov cx,aleng        ; get loop count
  241. p125:    loop p125        ; wait around
  242.     pop ax            ; restore original port value
  243.     out 61h,al        ; turn speaker off
  244.     pop cx
  245.     pop ax
  246.     ret
  247. p120    endp
  248.  
  249. p150:                ; start of transient code
  250.     mov dx,offset copyr
  251.     call p220        ; print copyright
  252.     mov ax,0
  253.     mov es,ax        ; segment 0
  254.     mov di,segaddr+2    ; this program's prior location
  255.     mov ax,es:[di]        ; get prior code segment
  256.     mov es,ax        ; point to prior program segment
  257.     mov di,offset signature
  258.     mov cx,es:[di]        ; is it this program?
  259.     cmp cx,whozat
  260.     jnz p160        ; no - install it
  261.     call p200        ; set state & alarm
  262.     int 20h         ; terminate
  263.  
  264. p160:    mov di,segaddr+2    ; point to int 62h
  265.     mov ax,0
  266.     mov es,ax        ; segment 0
  267.     mov ax,ds        ; get current ds
  268.     mov es:[di],ax        ; set int 62h
  269.     mov si,offset jumpval
  270.     mov di,intaddr        ; point to timer interrupt
  271.     mov bx,es:[di]        ; get timer ip
  272.     mov ax,es:[di+2]    ; and cs
  273.     mov [si],bx        ; save prior ip
  274.     mov [si+2],ax        ; and cs
  275.     mov bx,offset p000
  276.     mov ax,ds
  277.     cli            ; clear interrupts
  278.     mov es:[di],bx        ; set new timer interrupt
  279.     mov es:[di+2],ax
  280.     sti            ; set interrupts
  281.     push ds
  282.     pop es
  283.     call p200        ; set state & alarm
  284.     mov dx,offset p150    ; last byte of resident portion
  285.     inc dx
  286.     int 27h         ; terminate
  287.  
  288. p200    proc near        ; set state & alarm
  289.     mov si,80h        ; point to command line
  290.     mov ax,0
  291.     mov di,0ffffh        ; init hours
  292.     mov bh,0
  293.     mov ch,0
  294.     mov dh,0        ; : counter
  295.     mov es:[state],bh    ; turn clock on
  296.     mov cl,[si]        ; get length
  297.     jcxz p210        ; it's zero
  298.  
  299. p203:    inc si            ; point to next char
  300.     mov bl,[si]        ; get it
  301.     cmp bl,'-'              ; is it a minus?
  302.     jnz p204        ; no
  303.     mov es:[state],bl    ; turn clock off
  304.     push dx
  305.     mov dx,offset msg3    ; print msg
  306.     call p220
  307.     pop dx
  308.     jmp p206
  309.  
  310. p204:    cmp dh,2        ; seen 2nd colon?
  311.     jz p206         ; yes - ignore seconds
  312.     cmp bl,':'              ; colon?
  313.     jnz p205        ; no
  314.     inc dh
  315.     cmp dh,2        ; second colon?
  316.     jz p206         ; yes - ignore seconds
  317.     push cx
  318.     push dx
  319.     mov cx,60
  320.     mul cx            ; multiply current ax by 60
  321.     pop dx
  322.     pop cx
  323.     mov di,ax        ; save hours
  324.     mov ax,0
  325.     jmp p206
  326. p205:    cmp bl,'0'
  327.     jb p206         ; too low
  328.     cmp bl,'9'
  329.     ja p206         ; too high - can be a problem
  330.     sub bl,'0'              ; convert it to binary
  331.     push cx
  332.     push dx
  333.     mov cx,10
  334.     mul cx            ; multiply current value by 10
  335.     add ax,bx        ; and add latest digit
  336.     pop dx
  337.     pop cx
  338. p206:    loop p203        ; done yet?
  339.     cmp di,0ffffh        ; any time to set?
  340.     jz p210         ; no
  341.     add ax,di        ; add hours
  342.     cmp ax,24*60
  343.     jb p209         ; ok
  344.     mov dx,offset msg1    ; print error message
  345.     call p220
  346.     jmp p210
  347.  
  348. p209:    mov es:[atime],ax    ; save minutes past midnight
  349.     mov ax,5
  350.     mov es:[acount],ax    ; set alarm count
  351.     mov dx,offset msg2    ; print set msg
  352.     call p220
  353. p210:    ret
  354. p200    endp
  355.  
  356. p220    proc near        ; print message
  357.     push ax
  358.     mov ah,9
  359.     int 21h
  360.     pop ax
  361.     ret
  362. p220    endp
  363.  
  364. copyr    db 'ALARM - Copyright 1983 Data Base Decisions',10,13,'$'
  365. msg1    db 'Invalid time - must be from 00:00 to 23:59',10,13,'$'
  366. msg2    db 'Resetting alarm time',10,13,'$'
  367. msg3    db 'Turning clock display off',10,13,'$'
  368.  
  369. alarm    endp
  370. cseg    ends
  371. end    alarm
  372.